op {
  graph_op_name: "ParallelConcat"
  in_arg {
    name: "values"
    description: <<END
Tensors to be concatenated. All must have size 1 in the first dimension
and same shape.
END
  }
  out_arg {
    name: "output"
    description: <<END
The concatenated tensor.
END
  }
  attr {
    name: "shape"
    description: <<END
the final shape of the result; should be equal to the shapes of any input
but with the number of input values in the first dimension.
END
  }
  summary: "Concatenates a list of `N` tensors along the first dimension."
  description: <<END
The input tensors are all required to have size 1 in the first dimension.

For example:

```
# 'x' is [[1, 4]]
# 'y' is [[2, 5]]
# 'z' is [[3, 6]]
parallel_concat([x, y, z]) => [[1, 4], [2, 5], [3, 6]]  # Pack along first dim.
```

The difference between concat and parallel_concat is that concat requires all
of the inputs be computed before the operation will begin but doesn't require
that the input shapes be known during graph construction.  Parallel concat
will copy pieces of the input into the output as they become available, in
some situations this can provide a performance benefit.
END
}
